package com.deyuanyun.pic.web.interceptor;

import com.deyuanyun.pic.cache.SessionCacheSupport2;
import com.deyuanyun.pic.common.util.ObjectUtil;
import com.deyuanyun.pic.common.util.ajax.AjaxSupport;
import com.deyuanyun.pic.controller.dto.UserSessionVO;
import com.deyuanyun.pic.domain.prvlg.CustomUser;
import com.deyuanyun.pic.web.support.ApplicationPropertiesListener;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * session过滤器未登录的返回到登陆页面
 * ajax请求则返回错误信息
 */
public class SessionVOInterceptor extends HandlerInterceptorAdapter {
    private static final Logger logger = Logger.getLogger(SessionVOInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {

        if (ApplicationPropertiesListener.devMod){
            CustomUser user=new CustomUser();
            user.setUsername("admin");
            request.getSession().setAttribute("username", "admin");
            com.deyuanyun.pic.web.utils.SecurityUtils.setUser(user);
        }

        //List<String> AjaxMode = getParmByName(request.getParameterMap(), "AjaxMode", null);
        //首先去除一些非法参数
        Map<String,String[]> m = new HashMap<String,String[]>(request.getParameterMap());
        for (Map.Entry entry:m.entrySet()){
            Object v=entry.getValue();
            if (v==null){
                continue;
            }
            String[] vv= (String[]) v;
            //List[] ls=new List[]{MyCollectionUtil.arr2ArrayList(vv),MyCollectionUtil.arr2ArrayList( ParameterFilter.safeless)};
            for (String vs:vv){
                if (vs!=null && vs.length()>4000){
                    AjaxSupport.sendFailText("paramFail",entry.getKey()+"参数太长!不能超过4000");
                    return false;

                }
                for (String p:ParameterFilter.safeless){
                    if (StringUtils.contains(vs,p)){
                        AjaxSupport.sendFailText("paramFail","含有非法参数!");
                        return false;
                    }
                }
            }
        }
        //request = new ParameterFilter((HttpServletRequest)request, m);

        String currURL=request.getRequestURI();
        /**判断是否是免登录页面*/
        if (isInWhiteBill(currURL)){
            return true;
        }
        if (SessionVOInterceptor.isInWhiteBillContains(currURL)){
            return true;
        }
        /**判断是否有登录信息*/
        HttpSession session = request.getSession();
        if(session==null){
            logger.error(">>>session为空");
            redirectLogin(request,response,session);
            return false;
        }
        Object o=session.getAttribute(SessionCacheSupport2.USERLOGINID);
        /*if (!UserSessionVO.class.equals(o.getClass())){
            return false;
        }*/
        if (ObjectUtil.isEmptyAll(o)){
            logger.error(">>>session中没有信息了");
            redirectLogin(request,response,session);
            return false;
        }
        String loginId=o.toString();
        UserSessionVO sessionVO=SessionCacheSupport2.get(loginId);
        //如果缓存中没有信息了，也需要重新登录
        if (sessionVO==null
                ||StringUtils.isBlank(sessionVO.getUsername())
                ||StringUtils.isBlank(sessionVO.getSessionID())){
            logger.error(">>>缓存中没有信息了");
            redirectLogin(request,response,session);
            return false;
        }
        //如果session中的username和缓存中的不一致!
        if (!loginId.equals(sessionVO.getUsername())){
            logger.error(">>>用户名session和缓存不一致!"+loginId+">>"+sessionVO.getUsername());
            redirectLogin(request,response,session);
            return false;
        }
        //如果sessionid也不一致
        if (!session.getId().equals(sessionVO.getSessionID())){
            logger.error(">>>sessionID session和缓存不一致!");
            redirectLogin(request,response,session);
            return false;
        }

        return true;

    }


private void redirectLogin(HttpServletRequest request,HttpServletResponse response,HttpSession session)
        throws Exception{
    Map<String, String[]> map =request.getParameterMap();
    List<String> AjaxMode = getParmByName(map, "AjaxMode", null);
    if(!ObjectUtil.isEmptyAll(AjaxMode)){
        AjaxSupport.sendFailText("sessionStatusFalse","未登录或者已过期");
        return;
    }
    if (session!=null){
        session.removeAttribute(SessionCacheSupport2.USERLOGINID);
        session.invalidate();
    }
    response.sendRedirect(request.getContextPath()+"/login.html");
}

    /**在参数request的参数map内，查找指定条件的的参数*/
    public static List<String> getParmByName(Map<String, String[]> map,String startWith,String endWith){
        List<String> stringList = new ArrayList<String>();
        if (map==null || map.isEmpty() || StringUtils.isEmpty(startWith)) {
            return stringList;
        }
        if (StringUtils.isNotEmpty(endWith)){
            for(Map.Entry _o : map.entrySet()){
                String s=_o.getKey().toString();
                if (s.startsWith(startWith) && s.endsWith(endWith)){
                    String _v =  ((String[])_o.getValue())[0];
                    if (_v!=null && !"".equals(_v)){
                        stringList.add(_v);
                    }

                }
            }
        }else {
            String[] strings = (String[])map.get(startWith);
            if (strings!=null && strings.length>0){
                String _v =  strings[0];
                if (_v!=null && !"".equals(_v)){
                    stringList.add((String)_v);
                }
            }

        }
        return stringList;
    }

/**一些不需要验证登陆直接通行的请求*/
    public static boolean isInWhiteBill(String url){
        List<String> wurlList=new ArrayList<String>();
        wurlList.add("/login.json");//登陆操作
        wurlList.add("/index.html");//登陆页操作
        wurlList.add("/loginout.html");
        wurlList.add("/cleanPipeLineManager/findAllMapData.json");//查询数据管理的坐标信息用于地图展示
        for (String s:wurlList){
            if (url.endsWith(s)){
                return true;
            }
        }

        return false;
    }
    public static boolean isInWhiteBillContains(String url){
        List<String> wurlList=new ArrayList<String>();
        wurlList.add("/app/");
        wurlList.add("/image/");
        for (String s:wurlList){
            if (StringUtils.contains(url,s)){
                return true;
            }
        }

        return false;
    }
}
